import {
  Injectable,
  NotFoundException,
  ForbiddenException,
  ConflictException,
} from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreateChatRoomDto } from './dto/create-chatroom.dto';
import { JoinChatRoomDto } from './dto/join-chatroom.dto';
import { SearchChatRoomDto } from './dto/search-chatroom.dto';
import * as bcrypt from 'bcrypt';

@Injectable()
export class ChatRoomService {
  constructor(private prisma: PrismaService) {}

  async createChatRoom(userId: number, createChatRoomDto: CreateChatRoomDto) {
    const {
      name,
      description,
      isPublic = true,
      isSearchable = true,
      password,
      maxUsers = 100,
    } = createChatRoomDto;

    // 检查聊天室名称是否已存在
    const existingRoom = await this.prisma.chatRoom.findFirst({
      where: { name },
    });

    if (existingRoom) {
      throw new ConflictException('聊天室名称已存在');
    }

    // 如果有密码，加密密码
    let hashedPassword = null;
    if (password) {
      hashedPassword = await bcrypt.hash(password, 10);
    }

    // 创建聊天室
    const chatRoom = await this.prisma.chatRoom.create({
      data: {
        name,
        description,
        isPublic,
        isSearchable,
        password: hashedPassword,
        maxUsers,
        ownerId: userId,
        users: {
          create: {
            userId,
            role: 'owner',
          },
        },
      },
      include: {
        owner: {
          select: {
            id: true,
            username: true,
            avatar: true,
          },
        },
        users: {
          include: {
            user: {
              select: {
                id: true,
                username: true,
                avatar: true,
              },
            },
          },
        },
        _count: {
          select: {
            users: true,
            messages: true,
          },
        },
      },
    });

    return chatRoom;
  }

  async searchChatRooms(searchDto: SearchChatRoomDto) {
    const { keyword, page = 1, limit = 10 } = searchDto;
    const skip = (page - 1) * limit;

    const where = {
      isSearchable: true,
      ...(keyword && {
        OR: [
          { name: { contains: keyword } },
          { description: { contains: keyword } },
        ],
      }),
    };

    const [chatRooms, total] = await Promise.all([
      this.prisma.chatRoom.findMany({
        where,
        skip,
        take: limit,
        include: {
          owner: {
            select: {
              id: true,
              username: true,
              avatar: true,
            },
          },
          _count: {
            select: {
              users: true,
              messages: true,
            },
          },
        },
        orderBy: { createdAt: 'desc' },
      }),
      this.prisma.chatRoom.count({ where }),
    ]);

    return {
      chatRooms,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    };
  }

  async getChatRoomById(chatRoomId: number, userId: number) {
    const chatRoom = await this.prisma.chatRoom.findUnique({
      where: { id: chatRoomId },
      include: {
        owner: {
          select: {
            id: true,
            username: true,
            avatar: true,
          },
        },
        users: {
          include: {
            user: {
              select: {
                id: true,
                username: true,
                avatar: true,
              },
            },
          },
        },
        _count: {
          select: {
            users: true,
            messages: true,
          },
        },
      },
    });

    if (!chatRoom) {
      throw new NotFoundException('聊天室不存在');
    }

    // 检查用户是否在聊天室中
    const isMember = chatRoom.users.some((user) => user.userId === userId);
    if (!isMember && !chatRoom.isPublic) {
      throw new ForbiddenException('您没有权限访问此聊天室');
    }

    return chatRoom;
  }

  async joinChatRoom(
    chatRoomId: number,
    userId: number,
    joinDto: JoinChatRoomDto,
  ) {
    const chatRoom = await this.prisma.chatRoom.findUnique({
      where: { id: chatRoomId },
    });

    if (!chatRoom) {
      throw new NotFoundException('聊天室不存在');
    }

    // 检查用户是否已经在聊天室中
    const existingMember = await this.prisma.chatRoomUser.findUnique({
      where: {
        userId_chatRoomId: {
          userId,
          chatRoomId,
        },
      },
    });

    if (existingMember) {
      throw new ConflictException('您已经在聊天室中');
    }

    // 检查聊天室是否已满
    const memberCount = await this.prisma.chatRoomUser.count({
      where: { chatRoomId },
    });

    if (memberCount >= chatRoom.maxUsers) {
      throw new ForbiddenException('聊天室已满');
    }

    // 如果有密码，验证密码
    if (chatRoom.password) {
      if (!joinDto.password) {
        throw new ForbiddenException('此聊天室需要密码');
      }

      const isPasswordValid = await bcrypt.compare(
        joinDto.password,
        chatRoom.password,
      );
      if (!isPasswordValid) {
        throw new ForbiddenException('密码错误');
      }
    }

    // 加入聊天室
    await this.prisma.chatRoomUser.create({
      data: {
        userId,
        chatRoomId,
        role: 'member',
      },
    });

    return { message: '成功加入聊天室' };
  }

  async leaveChatRoom(chatRoomId: number, userId: number) {
    const member = await this.prisma.chatRoomUser.findUnique({
      where: {
        userId_chatRoomId: {
          userId,
          chatRoomId,
        },
      },
      include: {
        chatRoom: true,
      },
    });

    if (!member) {
      throw new NotFoundException('您不在此聊天室中');
    }

    // 如果是房主，不能离开（需要转让或删除聊天室）
    if (member.role === 'owner') {
      throw new ForbiddenException(
        '房主不能离开聊天室，请转让房主权限或删除聊天室',
      );
    }

    await this.prisma.chatRoomUser.delete({
      where: {
        userId_chatRoomId: {
          userId,
          chatRoomId,
        },
      },
    });

    return { message: '已离开聊天室' };
  }

  async getUserChatRooms(userId: number) {
    const chatRooms = await this.prisma.chatRoomUser.findMany({
      where: { userId },
      include: {
        chatRoom: {
          include: {
            owner: {
              select: {
                id: true,
                username: true,
                avatar: true,
              },
            },
            _count: {
              select: {
                users: true,
                messages: true,
              },
            },
          },
        },
      },
      orderBy: {
        chatRoom: {
          updatedAt: 'desc',
        },
      },
    });

    return chatRooms.map((item) => ({
      ...item.chatRoom,
      userRole: item.role,
      isOnline: item.isOnline,
      lastSeen: item.lastSeen,
    }));
  }
}
